package com.kx.center.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;

public class WPosUtil {

	private static final String sign_type = "MD5";
	private static final String bp_id = "55dc1561fa0bab42b2c2b3d0";
	private static final String key = "L8hS2nhIlietf3el83z9wfjpQUVjHghd";
	private static final String notify_url = "http://apps.weipass.cn/cashier/openapi/orderinfo/query";

	private static final String charset = "UTF-8";

	public static String getPaymentInfo(String outTradeNo) throws NoSuchAlgorithmException,
			HttpException, IOException {

		Map<String, String> sigMap = new HashMap<String, String>();
		sigMap.put("bp_id", bp_id);
		sigMap.put("out_trade_no", outTradeNo);
		sigMap.put("input_charset", charset);
		String sign = getSign(sigMap);

		Map<String, String> paramsMap = new HashMap<String, String>();
		paramsMap.put("sign_type", sign_type);
		paramsMap.put("sign", sign);
		paramsMap.put("bp_id", bp_id);
		paramsMap.put("out_trade_no", outTradeNo);
		paramsMap.put("input_charset", charset);

		String params = WPosUtil.concatParams(paramsMap);
		String json = WPosUtil.post(notify_url, params);
		
		return json;
	}

	public static String getSign(Map<String, String> dataMap) throws NoSuchAlgorithmException,UnsupportedEncodingException {
		
		List<String> keyList = new ArrayList<String>(dataMap.keySet());
		Collections.sort(keyList);
		StringBuilder builder = new StringBuilder();
		for (String mapKey : keyList) {
			builder.append(mapKey).append("=").append(dataMap.get(mapKey))
					.append("&");
		}
		builder.append("key=").append(key);
		MessageDigest md5 = MessageDigest.getInstance(sign_type);
		md5.update(builder.toString().getBytes(charset));
		byte[] md5Bytes = md5.digest();
		StringBuffer hexValue = new StringBuffer();
		for (int i = 0; i < md5Bytes.length; i++) {
			int val = ((int) md5Bytes[i]) & 0xff;
			if (val < 16) {
				hexValue.append("0");
			}
			hexValue.append(Integer.toHexString(val));
		}
		return hexValue.toString();
	}

	public static String post(String url, String data) throws HttpException,
			IOException {

		HttpClient httpclient = new HttpClient();
		PostMethod method = new PostMethod(url);

		StringRequestEntity requestEntity = new StringRequestEntity(data,
				"application/x-www-form-urlencoded", "UTF-8");
		method.setRequestEntity(requestEntity);

		int code = httpclient.executeMethod(method);

		byte[] responseBody = null;

		if (code == HttpStatus.SC_OK) {
			Header contentEncoding = method
					.getResponseHeader("Content-Encoding");
			if (contentEncoding != null
					&& contentEncoding.getValue().toLowerCase().indexOf("gzip") > -1) {
				InputStream is = method.getResponseBodyAsStream();
				GZIPInputStream gzip = new GZIPInputStream(is);
				byte[] buf = new byte[1024];

				int num = -1;
				ByteArrayOutputStream baos = new ByteArrayOutputStream();

				while ((num = gzip.read(buf, 0, buf.length)) != -1) {
					baos.write(buf, 0, num);
				}
				responseBody = baos.toByteArray();
				baos.flush();
				baos.close();
				gzip.close();
				is.close();
			} else {
				responseBody = method.getResponseBody();
			}

			Header contentType = method.getResponseHeader("Content-Type");
			if (contentType != null) {
				String encoding = contentType.getValue().toUpperCase();

				Pattern pattern = Pattern.compile("CHARSET=([^;]*)");
				Matcher matcher = pattern.matcher(encoding);
				String charset = matcher.find() ? matcher.group(1) : null;

				if (charset != null) {
					responseBody = (new String(responseBody, charset))
							.getBytes("UTF-8");
				}
			}
		}
		String result = new String(responseBody);
		return result;
	}

	public static String concatParams(Map<String, String> params)
			throws UnsupportedEncodingException {
		Object[] key_arr = params.keySet().toArray();
		Arrays.sort(key_arr);
		String str = "";

		for (Object key : key_arr) {
			String val = params.get(key);
			key = URLEncoder.encode(key.toString(), "UTF-8");
			val = URLEncoder.encode(val, "UTF-8");
			str += "&" + key + "=" + val;
		}

		return str.replaceFirst("&", "");
	}

}
